#ifndef __BONUSBINGOGAMERESULT_H__
#define __BONUSBINGOGAMERESULT_H__

#include "lib.h"

#include <set>
#include <map>
#include <vector>
#include <functional>

#include "BonusBingoConstants.h"

using namespace BonusBingo;

class BonusBingoGame;
class BonusBingoCard;
class HitEvaluatorSet;

class BonusBingoGameResult  
{
public:   
    typedef std::vector<uint8> BallSet;

	BonusBingoGameResult(BonusBingoGame* game);

    static int32 GetPayout(BonusBingo::WinPatterns pattern );

	virtual ~BonusBingoGameResult();

    const BallSet& getSelectedBalls() const;

    bool8 addSelectedBall( uint8 ball );

    void setJokerValue( uint8 value );

    int32 getJokerValue() const;

    void evaluateGame();

    uint8 winsForCard( uint8 cardIndex ) const;

    BonusBingo::WinPatterns getWinPattern( uint8 cardIndex, uint8 winIndex )  const;

    uint8 multiplierValue( uint8 cardIndex ) const;

    int32 getWinPayout( uint8 cardIndex, uint8 winIndex ) const;

    int32 payout( uint8 cardIndex ) const;

	int32 getTotalPayout() const;    

	const BonusBingoGame& getGame() const;   

    void finalizeResults();

    void startRestore();

    void endRestore();

#ifdef DEBUG_KNOWNSPINS
    bool8   needsLastBall( uint8 ball ) const;
#endif

protected:
    //The hit masks for each pattern
    static const BonusBingo::HitMask HitMasks[ BonusBingo::WIN_PATTERN_COUNT ];

    //The payouts for each win pattern
    static const int32 g_Payouts[BonusBingo::WIN_PATTERN_COUNT];

    typedef std::set<uint8> InternalBallSet;

    //We'll need to remember each win pattern and the hit mask that produced it
    typedef std::pair<BonusBingo::WinPatterns, BonusBingo::HitMask> WinHitMaskPair;
    typedef std::vector<WinHitMaskPair> WinVector;

    std::vector< WinVector* > m_cardWins;

    BallSet m_selectedBalls;
    
    InternalBallSet m_internalSelectedBalls;

    BonusBingoGame* m_game;

    uint8   m_jokerValue;

    bool8   m_restoring;

    void getHitMask(const BonusBingoCard*, BonusBingo::HitMask& ) const;
    
    void addWin( uint8 cardIndex, BonusBingo::HitMask hitMask, 
                 BonusBingo::WinPatterns pattern );

    /******************************************************************************
    Helper functor class
    ******************************************************************************/
    struct WinOverlappedBy
    {
	protected:
        WinHitMaskPair m_testPattern;

	public:
        WinOverlappedBy( WinHitMaskPair testPattern );

        bool operator()(const WinHitMaskPair& lhs ) const;
    };    
};

#endif //__BONUSBINGOGAMERESULT_H__
